# code = 0  # 请求成功
# code = 1  # 返回失败数据
# code = 2  # 数据库操作异常
import json
import uuid
from django.contrib.auth.hashers import make_password, check_password
from django.core.paginator import Paginator
from django.db import transaction
from django.db.models import Q
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from shujuyuan.models import TdsdDataSource
from utils import util
from muluguanli.models import Mulu
from utils.util import request_body_serialize, api_verification, FormVerify
from yonghuguanli.models import TdsdUser, TdsdApplyResource, UserApi, TdsdMessage
from ziyuanguanli.models import TdsdResourceList

fv = FormVerify()  # 创建一个实例对象即可


def login(request):
    """用户登录界面及登录请求逻辑处理"""
    if request.method == 'GET':
        # 处理请求登录页面的逻辑
        # user = TdsdUser.objects.filter(id=request.session.get('user_id'), isdelete=0).first()
        if 'user_id' in request.session:
            # 如果用户登录过了，直接跳转到user_center，不能再次跳转到login_html
            return redirect('/user/center/')
        return render(request, 'login.html')
    elif request.method == 'POST':
        # 用户登录逻辑处理
        arg = request.POST
        print(arg)
        username = arg.get('username')
        _password = arg.get('password')
        # 从数据库获取用户名和密码，进行验证
        user = TdsdUser.objects.filter(username=username, isdelete=0)
        if user.count() == 1:
            # 验证密码
            if check_password(_password, user[0].password):
                # 判定登录成功，使用session记录用户登录状态
                request.session.set_expiry(0)  # 关闭浏览器时，失效
                user_id = user[0].id
                request.session['user_id'] = user_id
                request.session['username'] = username  # 前端用来展示用户名用的
                request.session['level_id'] = user[0].level_id
                resp = JsonResponse({'code': 0, 'msg': 'Success'})
                resp.set_cookie('ui', user_id)
                return resp
            else:
                return JsonResponse({'code': 1, 'msg': '密码错误'})
        else:
            return JsonResponse({'code': 1, 'msg': '用户名不存在'})


@util.user_login
def account_manage(request):
    """返回用户管理页面，超级管理才有权限进入，前端需要异步获取所有用户的信息，根目录信息直接渲染在模板内"""
    user_id = request.session.get('user_id')
    level_id = request.session.get('level_id')  # 登录后session中保存的有此值
    dir_id = request.GET.get('dir_id')
    # 检验是否是超级管理员None
    user = TdsdUser.objects.filter(id=user_id)
    if level_id == 0:  # 超级管理员得到的是不同的页面
        if len(user) == 1:
            level_id = request.GET.get('level_id')
            dirs = Mulu.objects.filter(parent_id=None, isdelete=0).values('id', 'name')
            if dir_id:
                print('dir_id', dir_id)
                context = {'dirs': dirs, 'title': '系统管理', 'dir_id': dir_id}
            elif level_id:
                context = {'dirs': dirs, 'title': '系统管理', 'level_id': level_id}
            else:
                context = {'dirs': dirs, 'title': '系统管理'}
            context['title'] = '用户管理'
            return render(request, 'account_manage.html', context)
        else:
            return HttpResponse('账号异常，请联系超级管理员')
    else:  # 普通用户得到的是已经通过审核的资源列表
        return redirect('/user/resource/application/1/')


# @ensure_csrf_cookie
# @util.user_login
# def sys_manage(request):
#     """返回用户管理页面，超级管理才有权限进入，前端需要异步获取所有用户的信息，根目录信息直接渲染在模板内"""
#     user_id = request.session.get('user_id')
#     level_id = request.session.get('level_id')  # 登录后session中保存的有此值
#     # 检验是否是超级管理员None
#     user = TdsdUser.objects.filter(id=user_id, isdelete=0)
#     if level_id == 0:  # 超级管理员得到的是不同的页面
#         if len(user) == 1:
#             dirs = Mulu.objects.filter(parent_id=None, isdelete=0).values('id', 'name')
#             context = {'dirs': dirs, 'title': '系统管理', 'level_id': level_id}
#             return render(request, 'account_manage.html', context)
#         else:
#             return HttpResponse('用户id异常，请联系超级管理员')
#     else:  # 普通用户得到的是已经通过审核的资源列表
#         return redirect('/user/resource/application/1/')


# def dirs(request):
#     """专门用来获取共有多少个目录,返回前端来展示目录"""
#     dirs = Mulu.objects.filter(parent_id=None, isdelete=0).values('id', 'name')
#     return JsonResponse({'dirs': list(dirs)})


@util.user_login
def user_info(request):
    """超级管理员关于用户信息的操作"""
    user_id = request.session.get('user_id')  # 超级管理员的id
    user = TdsdUser.objects.filter(id=user_id, isdelete=0)
    if len(user) == 1:
        level_id = request.session.get('level_id')
        if level_id == 0:  # 只有超级管理员才可以进行以下操作
            if request.method == 'POST':  # 添加新用户
                arg = request.POST
                # 获取数据
                username = arg.get('username')
                _password = arg.get('password')
                password = make_password(_password)
                # print(password)
                dir_id = arg.get('dir')  # 整数，需要转换
                level_id = arg.get('role')  # 整数，需要转换
                telephone = arg.get('telephone')  # 可以为空，用户可自行设置
                # 对以上数据进行单独验证处理
                if not fv.verify_username(username):
                    return JsonResponse({'code': 1, 'msg': '用户名长度为5-60个字符，只能为数字字母汉字，且不能以数字开头'})
                elif not fv.verify_password(_password):
                    return JsonResponse({'code': 1, 'msg': '密码必须6到15位，且不能出现空格'})
                elif not fv.verify_telephone(telephone):
                    return JsonResponse({'code': 1, 'msg': '手机号格式有误，请重新输入'})

                if dir_id.isdigit():
                    dir_id = int(dir_id)  # 数字说明是正常前端传递
                elif dir_id != '':  # 创建管理员时，可以不指定部门，此时存入数据库中的是空字符串
                    # 非法传递
                    return JsonResponse({'code': 1, 'msg': '部门信息错误，请重新输入！'})
                elif dir_id == '':
                    # 绕过前端传递空字符串提交
                    # dir_id = None
                    return JsonResponse({"code": 1, 'msg': '部门信息不能为空，请重新输入！'})

                if level_id in ['1', '2'] and level_id.isdigit():
                    level_id = int(level_id)
                else:
                    return JsonResponse({'code': 1, 'msg': '请选择正确的用户角色'})
                appkey = str(uuid.uuid4()).replace('-', '')
                try:
                    with transaction.atomic():  # 开启事务，失败会自动回滚，并执行except中的代码
                        TdsdUser.objects.create(
                            username=username,
                            password=password,
                            dir_id=dir_id,
                            level_id=level_id,
                            telephone=telephone,
                            appkey=appkey
                        )
                        return JsonResponse({'code': 0, 'msg': 'Success'})
                except Exception as e:
                    return JsonResponse({'code': 2, 'msg': str(e)})
            elif request.method == 'GET':
                # 获取所有用户数据列表返回前端展示，数据表格的异步请求，不再进行是否删除的过滤
                arg = request.GET
                current_page = arg.get('page')  # 当前页码
                limit = arg.get('limit')  # 限制条目数
                search_info = arg.get('search_info')  # 搜索内容，用户名
                dir_id = arg.get('dir_id')  # 点击部门目录进入
                print(dir_id)
                level_id = arg.get('level_id')  # 点击角色目录进入
                if search_info and dir_id:
                    # 既选择了部门，又进行了搜索
                    users_obj = TdsdUser.objects.filter(username__contains=search_info, dir_id=dir_id).exclude(
                        level_id=0).order_by('-update_time')  # 没有删掉的，且不包括超级管理员
                elif search_info and level_id:
                    # 既选择了角色，又进行了搜索
                    users_obj = TdsdUser.objects.filter(username__contains=search_info, level_id=level_id).exclude(
                        level_id=0).order_by('-update_time')  # 没有删掉的，且不包括超级管理员
                elif search_info:  # 返回用户搜索的内容相关条目
                    users_obj = TdsdUser.objects.filter(username__contains=search_info).exclude(level_id=0).order_by(
                        '-update_time')  # 没有删掉的，且不包括超级管理员
                elif dir_id:  # 点击部门目录的操作进入此处
                    users_obj = TdsdUser.objects.filter(dir_id=dir_id).exclude(level_id=0).order_by('-update_time')
                elif level_id:  # 超级管理员不对外开放，点击角色目录
                    users_obj = TdsdUser.objects.filter(level_id=level_id).exclude(level_id=0).order_by('-update_time')
                else:  # 返回进入系统管理时显示内容
                    users_obj = TdsdUser.objects.exclude(level_id=0).order_by('-update_time')  # 没有删掉的，且不包括超级管理员
                count = users_obj.count()
                if count > 0:  # 有数据，返回
                    code = 0  # 代表成功
                    paginator = Paginator(users_obj, limit)
                    # 得到当前页的数据,返回
                    page = paginator.page(current_page)
                    data = []
                    for i, user in enumerate(page.object_list):
                        item = {}
                        # role_id和dir_id的用途是编辑时数据回显
                        item['id'] = i + 1  # 用于前端展示的编号
                        item['user_id'] = user.id  # 数据库真实id编号
                        item['username'] = user.username
                        # 根据用户的level_id设置对应的名称
                        item['role_id'] = user.level_id
                        if user.level_id == 1:
                            item['role'] = '管理员'
                        elif user.level_id == 2:
                            item['role'] = '访客'
                        item['status'] = user.isdelete
                        item['dir_id'] = user.dir_id  # dir_id有其他用途，因此需要返回
                        dir_obj = Mulu.objects.filter(id=user.dir_id, isdelete=0)
                        dir_obj = dir_obj if len(dir_obj) == 1 else None
                        if dir_obj:
                            item['dir'] = dir_obj[0].name  # 根目录名称
                        else:
                            item['dir'] = ''  # 有可能目录被删掉或者创建用户时没有指定目录
                        item['operator'] = '系统管理员'
                        item['update_time'] = str(user.update_time)
                        item['telephone'] = user.telephone
                        data.append(item)
                    resp = {"code": code, "count": count, "data": data}
                else:
                    code = 1
                    msg = '暂无相关数据!'
                    resp = {'code': code, 'msg': msg}
                return JsonResponse(resp)
            elif request.method == 'PUT':
                # 用户信息修改和密码重置操作
                arg = request_body_serialize(request)
                # 获取数据
                option = arg.get('option')  # 判断是否为重置密码操作,非重置密码option为None
                user_id = arg.get('user_id')
                # user = TdsdUser.objects.filter(id=user_id, isdelete=0)  # 未删除用户
                user = TdsdUser.objects.filter(id=user_id)
                user1 = TdsdUser.objects.filter(id=user_id, isdelete=1)  # 已删除用户
                if len(user1) == 1:  # 先判断是否是对删除的用户进行的操作
                    # 对已删除用户的进行账户恢复的操作，仅作状态更改，恢复之后，才可以进行其他操作，也就不再执行此处代码
                    try:
                        with transaction.atomic():
                            user1.update(isdelete=0)
                            return JsonResponse({'code': 0, 'msg': 'Success'})
                    except Exception as e:
                        return JsonResponse({'code': 2, 'msg': str(e)})
                elif len(user) == 1:
                    if option == 'reset_pwd':
                        try:
                            with transaction.atomic():  # 开启事务，失败会自动回滚，并执行except中的代码
                                # 用户名不得修改，因为根据的是user_id来判断当前用户的，和用户名无关
                                password = '123456'
                                _password = make_password(password)
                                user.update(password=_password)
                                return JsonResponse({'code': 0, 'msg': '密码重置为:%s' % password})
                        except Exception as e:
                            return JsonResponse({'code': 2, 'msg': str(e)})
                    # 以下为编辑修改用户信息的操作
                    dir_id = arg.get('dir') if arg.get('dir') else None  # TODO 暂时认为没有非法操作
                    level_id = arg.get('role')
                    telephone = arg.get('telephone')  # 可以为空，用户可自行设置
                    username = arg.get('username')
                    if not fv.verify_username(username):
                        return JsonResponse({'code': 1, 'msg': '用户名只能为数字字母汉字，且不能以数字开头'})
                    if not fv.verify_telephone(telephone):
                        return JsonResponse({'code': 1, 'msg': '手机号格式有误，请重新输入'})
                    try:
                        with transaction.atomic():
                            user.update(
                                username=username,
                                dir_id=dir_id,
                                level_id=level_id,
                                telephone=telephone,
                            )
                            return JsonResponse({'code': 0, 'msg': 'Success'})
                    except Exception as e:
                        return JsonResponse({'code': 2, 'msg': str(e)})
                else:
                    return JsonResponse({'code': 1, 'msg': '当前用户不存在'})
            elif request.method == 'DELETE':
                # 逻辑删除用户信息，删除前要判断用户名下是否有数据源，资源，目录等内容，有就不可以删除用户
                arg = request_body_serialize(request)
                user_id = arg.get('user_id')  # 要删除的用户的id
                # 在资源表，目录表，数据源表中有用户关联的数据，就不能删除
                resources = TdsdResourceList.objects.filter(userid=user_id, status=0)
                data_sources = TdsdDataSource.objects.filter(user_id=user_id)
                mulus = Mulu.objects.filter(user_id=user_id)
                print(resources, data_sources, mulus)
                if resources.count() > 0 or data_sources.count() > 0 or mulus.count() > 0:
                    return JsonResponse({'code': 1, 'msg': '该用户名下尚有数据未删除，请在删除后再进行此操作'})

                # 从公司表中找到对应的信息,然后逻辑删除
                user = TdsdUser.objects.filter(id=user_id, isdelete=0)
                if len(user) == 1:
                    try:
                        with transaction.atomic():
                            user.update(isdelete=True)
                            code = 0
                            msg = 'Success'
                    except Exception as e:
                        code = 2  # 数据库操作异常
                        msg = str(e)
                else:  # 已经删除过不能再次删除
                    msg = '用户已删除'
                    code = 1
                resp = {'code': code, 'msg': msg}
                return JsonResponse(resp)
        else:
            return JsonResponse({'code': 1, 'msg': '用户权限不足'})
    else:
        return JsonResponse({'code': 1, 'msg': '请使用管理员帐户登录后进行此操作'})


@util.user_login
def user_center(request):
    """用户中心页面渲染，用户信息修改逻辑处理，用户密码修改逻辑处理"""
    user_id = request.session.get('user_id')
    user = TdsdUser.objects.filter(id=user_id, isdelete=0)
    if len(user) == 1:
        if request.method == 'GET':
            # 查找出用户信息，渲染到页面中
            level_id = user[0].level_id
            username = user[0].username
            telephone = user[0].telephone if user[0].telephone else ''
            dir_id = user[0].dir_id
            # dir_name 需要单独查找
            dir_obj = Mulu.objects.filter(id=dir_id, isdelete=0).first()
            if dir_obj:
                dir_name = dir_obj.name
            else:
                dir_name = ''  # 当前用户的根目录被删除或未指定根目录，会执行此处
            context = {'title': '用户中心', 'level_id': level_id, 'username': username, 'telephone': telephone,
                       'dir_name': dir_name,
                       'dir_id': dir_id}
            return render(request, 'user_center.html', context)
        elif request.method == 'PUT':
            # 用户个人信息修改,超级管理员dir_id==None
            # 从数据库读取数据，根据前端传递信息判断，是否对用户名，部门，角色进行了修改
            arg = request_body_serialize(request)
            if arg.get('level_id') == str(user[0].level_id) and arg.get('dir_id') == str(
                    user[0].dir_id) and arg.get(
                'username') == str(user[0].username):
                telephone = arg.get('telephone')
                if not fv.verify_telephone(telephone):
                    return JsonResponse({'code': 1, 'msg': '手机号格式有误，请重新输入'})
                try:
                    with transaction.atomic():  # 开启事务，失败会自动回滚，并执行except中的代码
                        user.update(telephone=telephone)
                        return JsonResponse({'code': 0, 'msg': 'Success'})
                except Exception as e:
                    return JsonResponse({'code': 2, 'msg': str(e)})
            else:
                # 恶意请求，会导致此返回，篡改后台给前端页面设置的参数发送请求
                return JsonResponse({'code': 1, 'msg': '非法操作'})
        elif request.method == 'POST':
            # 用户修改密码操作
            arg = request.POST
            old_password = arg.get('old_password')  # 旧密码
            _password = arg.get('password')  # 新密码
            if not fv.verify_password(_password):
                return JsonResponse({'code': 1, 'msg': '密码必须6到15位，且不能出现空格'})
            repassword = arg.get('repassword')
            if check_password(_password, user[0].password):  # 校验新密码与旧密码是否一致
                return JsonResponse({'code': 1, 'msg': '新旧密码不能一致'})
            if check_password(old_password, user[0].password):  # 验证用户输入的原始密码是否正确
                if _password == repassword:  # 验证用户两次输入的新密码是否一致
                    try:
                        with transaction.atomic():  # 开启事务，失败会自动回滚，并执行except中的代码
                            password = make_password(_password)
                            user.update(password=password)
                            return JsonResponse({'code': 0, 'msg': 'Success'})
                    except Exception as e:
                        return JsonResponse({'code': 2, 'msg': str(e)})
                else:
                    return JsonResponse({'code': 1, 'msg': '两次输入新密码不一致'})
            else:
                return JsonResponse({'code': 1, 'msg': '原有密码错误'})
    else:
        return JsonResponse({'code': 1, 'msg': '请登录后再进行操作'})


@util.user_login
def password_html(request):
    """修改密码页面"""
    context = {'title': '修改密码'}
    return render(request, 'alter_password.html', context)


@util.user_login
def logout(request):
    """用户退出，删除数据库中保存的session记录"""
    request.session.flush()
    return redirect('/user/login/')


def reg_admin(request):
    """注册超级管理员用，方便一点，上线需要删除本函数"""
    # TODO 完成项目后注释掉
    if request.method == 'POST':
        arg = request.POST
        name = arg.get('name')
        pwd = arg.get('pwd')
        level_id = '0'
        try:
            with transaction.atomic():
                user = TdsdUser()
                user.level_id = level_id
                user.username = name
                user.password = make_password(pwd)
                user.appkey = str(uuid.uuid4()).replace('-', '')
                user.save()
                return HttpResponse('超级管理员注册成功')
        except Exception as e:
            print(e)
            return HttpResponse('数据库错误')
    elif request.method == 'GET':
        return render(request, 'supert_admin_register.html')


@util.user_login
def resource(request):
    """
    对申请资源表进行增加，删除，修改，以及获取拒绝原因
    :param request:
    :param cate: 0 表示用户作为申请者发送请求，1表示用户作为审核者发送请求
    :return:
    """
    if request.method == 'PUT':
        # 审核者对申请者的申请进行通过或拒绝操作
        arg = request_body_serialize(request)
        refuse_reason = arg.get('reason')
        r_id = arg.get('real_id')
        status = arg.get('status')
        sender_id = request.session.get('user_id')  # 当前此操作的用户id为信息发送者
        obj = TdsdApplyResource.objects.filter(id=r_id, isdelete=0)
        if refuse_reason and obj.count() == 1 and status == '2':  # 拒绝
            # TODO 此处代码应该可以优化
            _resource = TdsdResourceList.objects.filter(resource_id=obj.first().resource_id, status=0).first()
            if _resource:
                title = '你申请的 %s 资源被拒绝' % _resource.resource_name
                msg = '拒绝原因：%s' % refuse_reason
                try:
                    with transaction.atomic():
                        obj.update(status=status, isoperated=1)
                        # obj.update(refuse_reason=refuse_reason)
                        # 拒绝原因直接写入message表中，作为message字段的内容，等于refuse_reason字段无效
                        TdsdMessage.objects.create(
                            user_id=obj.first().apply_user_id,
                            title=title,
                            sender_id=sender_id,
                            message=msg,
                            message_url='/resource/desc/%s.html/' % _resource.resource_id,
                            apply_resource_tb_id=r_id
                        )
                except Exception as e:
                    return JsonResponse({'code': 2, 'msg': str(e)})
                return JsonResponse({'code': 0, 'msg': 'Success'})
            else:
                return JsonResponse({'code': 1, 'msg': '资源不存在'})
        elif obj.count() == 1 and status == '1':  # 通过
            # 需要在通过之前验证资源是否还存在
            _resource = TdsdResourceList.objects.filter(resource_id=obj.first().resource_id, status=0).first()
            if _resource:
                title = '你申请的 %s 资源已通过审核' % _resource.resource_name
                msg = '点击查看资源详情'  # 直接跳转到资源详情页
                token = str(uuid.uuid4()).replace('-', '')  # 只有审核通过，才会有token
                print(token)
                try:
                    with transaction.atomic():
                        obj.update(status=status, isoperated=1, token=token)
                        TdsdMessage.objects.create(
                            user_id=obj.first().apply_user_id,
                            title=title,
                            sender_id=sender_id,
                            message=msg,
                            message_url='/resource/desc/%s.html/' % _resource.resource_id,
                            apply_resource_tb_id=r_id
                        )
                except Exception as e:
                    return JsonResponse({'code': 2, 'msg': str(e)})
                    # 通过情况下，需要给申请者发送站内信，告知其申请通过
                return JsonResponse({'code': 0, 'msg': 'Success'})
            else:
                return JsonResponse({'code': 1, 'msg': '资源不存在'})
        else:
            return JsonResponse({'code': 1, 'msg': '参数有误'})
    elif request.method == 'POST':
        # 申请者点击申请按钮,将申请信息保存至数据库中
        arg = request.POST
        user_id = arg.get('user_id')
        resource_id = arg.get('resource_id')
        resource_user_id = arg.get('resource_user_id')

        # 资源id和资源所属用户id是否是匹配的
        res_obj = TdsdResourceList.objects.filter(resource_id=resource_id, userid=resource_user_id, status=0).first()
        if res_obj:
            resource_status = res_obj.resource_status
        else:
            return JsonResponse({'code': 1, 'msg': '资源不存在'})  # 防止绕过前端进行的申请
        # 判断此用户是否已经申请过此资源
        tar_obj = TdsdApplyResource.objects.filter(apply_user_id=user_id, isdelete=0, resource_id=resource_id,
                                                   status=0).first()
        if tar_obj:  # 说明已经申请过了
            # 如果用户已经申请过，前端页面不应当显示申请按钮，而现实  已申请
            # 用户进入资源详情页，异步发送请求，查询是否已经申请过了，是否已经通过申请，已通过的现实token，以上查询针对的是非公开资源，公开资源不进行以上查询
            # 通过user_id和resource_id在数据库查找是否存在来判断是否申请过
            return JsonResponse({'code': 1, 'msg': '你已申请过此资源，请勿重复申请'})  # 针对的是不是通过点击申请按钮的请求
        if res_obj and resource_status == 0:  # 根据状态判断资源是否需要申请
            # print(user_id, resource_user_id, resource_id)
            if user_id and resource_id and resource_user_id:
                # 三者缺一不可,否则影响后续操作
                try:
                    new_obj = TdsdApplyResource.objects.create(
                        apply_user_id=user_id,
                        resource_id=resource_id,
                        resource_user_id=resource_user_id
                    )
                    # 站内信给资源拥有者（审核者）设置一条记录
                    # 申请成功后，要发送消息给资源拥有者
                    apply_user = TdsdUser.objects.filter(id=user_id, isdelete=0).first()
                    apply_username = apply_user.username if apply_user else ""
                    title = '你的 %s 资源被 %s 申请了，请审核。' % (res_obj.resource_name, apply_username)
                    msg = '前往审核'  # 跳转到待审核区
                    TdsdMessage.objects.create(
                        user_id=resource_user_id,  # 此处的用户指的是审核者
                        title=title,
                        sender_id=user_id,  # 此处的发送者应当是申请者
                        message=msg,
                        message_url='/user/resource/review/0/?new_apply=%s' % new_obj.id,  # 跳转至审核资源列表的 待审核 页
                        apply_resource_tb_id=new_obj.id
                    )
                    return JsonResponse({'code': 0, 'msg': 'Success'})
                except Exception as e:
                    return JsonResponse({'code': 2, 'msg': str(e)})
        else:
            return JsonResponse({'code': 1, 'msg': '申请资源缺失或资源无需申请'})
    # elif request.method == 'DELETE':
    #     # 如果用户撤回申请,将其删除
    #     arg = request_body_serialize(request)
    #     real_id = arg.get('real_id')
    #     obj = TdsdApplyResource.objects.filter(id=real_id, isdelete=0)
    #     if obj.count() == 1:
    #         try:
    #             with transaction.atomic():
    #                 obj.update(isdelete=1)
    #         except Exception as e:
    #             return JsonResponse({'code': 2, 'msg': str(e)})
    #         return JsonResponse({'code': 0, 'msg': 'Success'})
    #     else:
    #         return JsonResponse({'code': 1, 'msg': '资源缺失'})
    elif request.method == 'GET':
        # 点击查看拒绝原因的请求
        arg = request.GET
        real_id = arg.get('real_id')
        apply_resource = TdsdApplyResource.objects.filter(id=real_id, isdelete=0).first()
        apply_user_id = apply_resource.apply_user_id if apply_resource else None
        # 通过user_id和apply_resource_tb_id能够确定唯一的message
        obj = TdsdMessage.objects.filter(apply_resource_tb_id=real_id, user_id=apply_user_id)  # real_id是站内信的真实具体id
        if obj.count() == 1:
            refuse_reason = obj.first().message
            return JsonResponse({'code': 0, 'msg': refuse_reason})
        else:
            return JsonResponse({'code': 1, 'msg': '无法获取消息或此申请已删除'})


@util.user_login
def msg_review_count(request):
    """数量的获取，同样需要登录后"""
    user_id = request.session.get('user_id')
    # 获取用户名下的新消息数量
    new_msg_count = TdsdMessage.objects.filter(user_id=user_id, status=0, isdelete=0).count()
    review_count = TdsdApplyResource.objects.filter(resource_user_id=user_id, status=0, isdelete=0).count()
    return JsonResponse({'new_msg_count': new_msg_count, 'review_count': review_count})


@util.user_login
def application(request, cate):
    """
    作为申请者，查看申请的资源列表信息
    :param request:
    :param cate: 3，表格数据异步请求；1，2，3都是获取申请资源列表页面的请求
    :return:
    """
    level_id = request.session.get('level_id')
    # level_id = request.GET.get('level_id')  # 如果携带有level_id
    user_id = request.session.get('user_id')
    if cate in ['0', '1', '2']:  # 根据cate来决定操作栏应当显示什么内容，以及表格异步请求数据的status设置
        dirs = Mulu.objects.filter(parent_id=None, isdelete=0).values('id', 'name')  # 目的是让左侧列表部门显示所有的部门
        all_r = request.GET.get('all_r')
        all_r = all_r if all_r == '1' else '0'  # 必须是1，0是普通用户
        title = '我的申请记录'
        return render(request, 'application.html', locals())
    elif cate == '3':  # 1 表格数据异步请求
        arg = request.GET
        current_page = arg.get('page')  # 当前页码
        limit = arg.get('limit')  # 限制条目数
        all_r = arg.get('all_r')  # 是否是超级管理员要获取所有的资源的判断条件，和level_id结合判断
        status = arg.get('status')
        # if all_r != '1':  # 只要这个参数有误，就是恶意请求
        #     return JsonResponse({"code": 0, "count": 0, "data": [], 'msg': '参数有误'})
        if not status:  # 请求所有数据，没有携带status参数
            # if level_id == 0 and all_r == '1':  # 超级管理看到所有的申请及审核
            #     objs = TdsdApplyResource.objects.filter(isdelete=0).order_by('-apply_time')
            # else:
            objs = TdsdApplyResource.objects.filter(isdelete=0, apply_user_id=user_id).order_by('-apply_time')
        elif status == '0':  # 待审核的请求
            # if level_id == 0 and all_r == '1':  # 超级管理看到所有的申请及审核
            #     objs = TdsdApplyResource.objects.filter(isdelete=0, status=0).order_by(
            #         '-apply_time')
            # else:
            objs = TdsdApplyResource.objects.filter(isdelete=0, status=0, apply_user_id=user_id).order_by(
                '-apply_time')
        elif status == '1':  # 审核已通过的请求
            # if level_id == 0 and all_r == '1':  # 超级管理看到所有的申请及审核
            #     objs = TdsdApplyResource.objects.filter(isdelete=0, status=1).order_by(
            #         '-apply_time')
            # else:
            objs = TdsdApplyResource.objects.filter(isdelete=0, status=1, apply_user_id=user_id).order_by(
                '-apply_time')
        elif status == '2':  # 审核被拒绝的请求
            # if level_id == 0 and all_r == '1':  # 超级管理看到所有的申请及审核
            #     objs = TdsdApplyResource.objects.filter(isdelete=0, status=2).order_by(
            #         '-apply_time')
            # else:
            objs = TdsdApplyResource.objects.filter(isdelete=0, status=2, apply_user_id=user_id).order_by(
                '-apply_time')
        else:  # 参数有误
            return JsonResponse({"code": 0, "count": 0, "data": []})
        # 需要去根据id获取对应的名称
        paginator = Paginator(objs, limit)
        # 得到当前页的数据,返回
        page = paginator.page(current_page)
        data_list = list()  # 无数据时，返回空列表，前端自动
        for i, obj in enumerate(page.object_list):
            _resource = TdsdResourceList.objects.filter(resource_id=obj.resource_id).first()
            item = dict()
            if _resource:
                item['id'] = i + 1
                item['real_id'] = obj.id
                item['resource_id'] = obj.resource_id
                item['resource_name'] = _resource.resource_name
                dir_obj = Mulu.objects.filter(id=_resource.resource_cate).first()
                item['dir'] = dir_obj.name  # TODO 有可能不存在，这里会报错
                while dir_obj.parent_id:
                    dir_obj = Mulu.objects.filter(id=dir_obj.parent_id).first()
                item['root_dir'] = dir_obj.name  # 资源所属根目录
                item['apply_time'] = str(obj.apply_time)
                # if level_id == 0 and all_r == '1':  # TODO 如果是超级管理员，多出申请者名字和资源拥有者（应该改为审核者）的名字
                #     resource_user = TdsdUser.objects.filter(id=obj.resource_user_id, isdelete=0).first()
                #     item['resource_user_name'] = resource_user.username if resource_user else '数据缺失'
                #     apply_user = TdsdUser.objects.filter(id=obj.apply_user_id, isdelete=0).first()
                #     item['apply_user_name'] = apply_user.username if apply_user else '数据缺失'
                status = obj.status
                item['status'] = status if status else ''
                item['isdelete'] = _resource.status  # 数据资源是否被删除
                # if status == 2:  # 被拒绝，返回拒绝原因
                #     # 消息列表删除后，拒绝原因还需要查看，因此不能是过滤删掉的消息
                #     msg_obj = TdsdMessage.objects.filter(apply_resource_tb_id=obj.id, user_id=obj.apply_user_id).first()
                #     item['refuse_reason'] = msg_obj.message if msg_obj else '未查询到相关信息'
                data_list.append(item)
                # else:
                #     item['id'] = i + 1
                #     item['resource_name'] = '资源已删除'
                #     data_list.append(item)
        resp = {"code": 0, "count": objs.count(), "data": data_list}
        return JsonResponse(resp)


@util.user_login
def review(request, cate):
    user_id = request.session.get('user_id')
    arg = request.GET

    if cate == '12' or cate == '0':  # 返回页面，根据cate来觉得是否显示操作栏
        dirs = Mulu.objects.filter(parent_id=None, isdelete=0).values('id', 'name')
        # review_id = request.GET.get('review_id') if request.GET.get('review_id') else ''
        new_apply_id = arg.get('new_apply') if arg.get('new_apply') else ''  # 只在点击前往审核时才会存在，其他时候都不存在
        review_id = arg.get('review_id') if arg.get('review_id') else ''
        # print('new_apply_id', new_apply_id)
        if new_apply_id:  # 没有这个 参数，就是None，不为None，是点击前往请求过来的
            obj = TdsdApplyResource.objects.filter(isdelete=0, status=0,
                                                   id=new_apply_id).first()  # 存在，则代表有申请等待审核，否则就是没有需要审核的申请
            if not obj:
                return redirect('/user/resource/review/12/?review_id={}'.format(new_apply_id))
        title = '我的审核记录'
        return render(request, 'review.html', locals())
    elif cate == '1':  # 1 表格数据异步请求
        current_page = arg.get('page')  # 当前页码
        limit = arg.get('limit')  # 限制条目数
        # 通过用户id在申请表中找到此用户名下的所有信息
        status = arg.get('status')
        if status == '12':  # 已审核的
            review_id = arg.get('review_id')
            if review_id:  # 点击前往审核按钮进此处获取数据
                objs = TdsdApplyResource.objects.filter(~Q(status=0), isdelete=0, id=review_id)
            else:
                objs = TdsdApplyResource.objects.filter(~Q(status=0), isdelete=0, resource_user_id=user_id).order_by(
                    '-apply_time')
        elif status == '0':  # 待审核
            new_apply_id = arg.get('new_apply_id')
            if new_apply_id:  # 从点击查看详情跳转至此
                # print(type(new_apply_id))
                # print(new_apply_id, 'new_apply_id')
                objs = TdsdApplyResource.objects.filter(isdelete=0, status=0, id=new_apply_id).order_by(
                    '-apply_time')
                # 如果objs是空，说明点击查看详情过来时，这个申请已经被审核了，因此需要重定向到已审核列表
                # print(objs)
                # if not objs:
                #     print(new_apply_id)
                #     print(111111111111)
                #     return redirect('/user/resource/review/12/?reviewed_id={}'.format(new_apply_id))
            else:
                objs = TdsdApplyResource.objects.filter(isdelete=0, status=0, resource_user_id=user_id).order_by(
                    '-apply_time')
        else:  # 参数有误
            return JsonResponse({"code": 0, "count": 0, "data": []})
        paginator = Paginator(objs, limit)
        # 得到当前页的数据,返回
        page = paginator.page(current_page)
        data_list = list()  # 无数据时，返回空列表，前端自动
        # print(objs)
        for i, obj in enumerate(page.object_list):
            item = dict()
            item['id'] = i + 1
            item['real_id'] = obj.id
            user = TdsdUser.objects.filter(id=obj.apply_user_id).first()
            item['apply_user_name'] = user.username if user else '申请人账户信息缺失'
            dir_obj = Mulu.objects.filter(id=user.dir_id).first()
            item['apply_user_dir'] = dir_obj.name if dir_obj else '部门信息缺失'
            _resource = TdsdResourceList.objects.filter(resource_id=obj.resource_id).first()
            item['isdelete'] = _resource.status
            item['resource_name'] = _resource.resource_name if _resource else '资源缺失'
            item['apply_time'] = str(obj.apply_time)
            status = obj.status
            item['status'] = status
            # if status == 2:  # 被拒绝的，审核者要看到是什么原因

            #     msg_obj = TdsdMessage.objects.filter(user_id=obj.apply_user_id, apply_resource_tb_id=obj.id, isdelete=0).first()
            #     item['refuse_reason'] = msg_obj.message if msg_obj else '未查询到相关信息'
            #     print(item['refuse_reason'])
            data_list.append(item)
        resp = {"code": 0, "count": objs.count(), "data": data_list}
        return JsonResponse(resp)


def shenqing(request):
    # 给每个用户添加一个appkey
    users = TdsdUser.objects.all()
    print(users)
    for user in users:
        u = str(uuid.uuid4()).replace('-', '')
        user.appkey = u
        user.save()
    return render(request, 'shenqing.html', locals())


@util.user_login
def userapirecord(request):
    """渲染页面"""
    dirs = Mulu.objects.filter(parent_id=None, isdelete=0).values('id', 'name')
    count = {'dirs': dirs, 'title': 'API使用记录'}
    return render(request, "api_userecord.html", count)


def useapiinfo(request):
    """api使用记录表"""
    response_data = {}
    arg = request.GET
    current_page = arg.get('page')  # 当前页码
    limit = arg.get('limit')  # 限制条目数
    search_info = arg.get('search_info')  # 搜索内容
    status = arg.get('resource_status')  # 资源状态，公开、需授权
    level_id = request.session.get('level_id')
    if level_id == 0:  # 判断是否为超级管理员，如果是查询所有api使用记录，否则查询自己创建的api使用记录
        if search_info and status: # 搜索内容及是否公开都存在：
            if int(status) == 1:
                userapi_obj = UserApi.objects.filter(resouce_status=1).filter(
                Q(api__contains=search_info) | Q(user_ip__contains=search_info)).order_by("-usetime")
            elif int(status) == 2:
                userapi_obj = UserApi.objects.filter(resouce_status=0).filter(
                Q(api__contains=search_info) | Q(user_ip__contains=search_info)).order_by("-usetime")
            else:
                userapi_obj = UserApi.objects.filter(
                    Q(api__contains=search_info) | Q(user_ip__contains=search_info)).order_by(
                    "-usetime")
        elif search_info: # by搜索内容查询
            userapi_obj = UserApi.objects.filter(
                Q(api__contains=search_info) | Q(user_ip__contains=search_info)).order_by(
                "-usetime")
        elif status: # by 是否公开查询
            if int(status) == 1:
                userapi_obj = UserApi.objects.filter(resouce_status=1).order_by("-usetime")
            elif int(status) == 2:
                userapi_obj = UserApi.objects.filter(resouce_status=0).order_by("-usetime")
            else:
                userapi_obj = UserApi.objects.all().order_by("-usetime")
        else:
            userapi_obj = UserApi.objects.all().order_by("-usetime")
    else: # 不是超级管理员登录：
        user_id = request.session.get('user_id')
        if search_info and status:
            if int(status) == 1:
                userapi_obj = UserApi.objects.filter(resouce_status=1, create_id=user_id).filter(Q(api__contains=search_info) | Q(user_ip__contains=search_info)).order_by("-usetime")
            elif int(status) == 2:
                userapi_obj = UserApi.objects.filter(resouce_status=0, create_id=user_id).filter(Q(api__contains=search_info) | Q(user_ip__contains=search_info)).order_by("-usetime")
            else:
                userapi_obj = UserApi.objects.filter((Q(api__contains=search_info) | Q(user_ip__contains=search_info)),
                                                     create_id=user_id).order_by("-usetime")
        elif search_info:
            userapi_obj = UserApi.objects.filter((Q(api__contains=search_info) | Q(user_ip__contains=search_info)),
                                                 create_id=user_id).order_by("-usetime")
        elif status:
            if int(status) == 1:
                userapi_obj = UserApi.objects.filter(resouce_status=1, create_id=user_id).order_by("-usetime")
            elif int(status) == 2:
                userapi_obj = UserApi.objects.filter(resouce_status=0, create_id=user_id).order_by("-usetime")
            else:
                userapi_obj = UserApi.objects.filter(create_id=user_id).order_by("-usetime")
        else:
            userapi_obj = UserApi.objects.filter(create_id=user_id).order_by("-usetime")
    if userapi_obj:
        count = userapi_obj.count()
        paginator = Paginator(userapi_obj, limit)
        page = paginator.page(current_page)
        for index, i in enumerate(page.object_list):
            user_name = TdsdUser.objects.get(id=i.user_id).username
            create_name = TdsdUser.objects.filter(id=i.create_id)
            if create_name:
                create_name = TdsdUser.objects.filter(id=i.create_id).first().username
            else:
                create_name = ''
            response_data.setdefault('data', []).append({
                'id': index + 1,  # 生成序号
                'username': user_name,
                'createname': create_name,
                'api': i.api,
                'user_ip': i.user_ip,
                'usetime': str(i.usetime)
            })

        response_data['code'] = 0
        response_data['count'] = count
        # print(response_data)
        return JsonResponse(response_data)
    else:
        response_data['code'] = 1
        response_data['msg'] = '暂无数据'
        return JsonResponse(response_data)


@util.user_login
def message(request, cate):
    """
    消息中心页面及表格的处理
    :param request:
    :param cate: 消息类型：0新消息，1已读，2全部，3表格异步获取数据
    :return:
    """
    if cate in ['0', '1', '2']:  # 新消息页面
        dirs = Mulu.objects.filter(parent_id=None, isdelete=0).values('id', 'name')
        title = '我的消息'
        return render(request, 'message.html', locals())
    elif cate == '3':  # 表格异步获取数据，根据status来确定需要的是哪种消息类型
        # 0 未读，1 已读，2 全部
        arg = request.GET
        current_page = arg.get('page')  # 当前页码
        limit = arg.get('limit')  # 限制条目数
        status = arg.get('status')
        user_id = request.session.get('user_id')
        if status == '0':
            msg_objs = TdsdMessage.objects.filter(user_id=user_id, status=status, isdelete=0).order_by('-push_time')
        elif status == '1':
            msg_objs = TdsdMessage.objects.filter(user_id=user_id, status=status, isdelete=0).order_by('-push_time')
        elif status == '2':  # 先按是否查看排序，然后按时间先后排序
            msg_objs = TdsdMessage.objects.filter(user_id=user_id, isdelete=0).order_by('status', '-push_time')
        else:  # 参数有误
            return JsonResponse({"code": 0, "count": 0, "data": []})
        paginator = Paginator(msg_objs, limit)
        # 得到当前页的数据,返回
        page = paginator.page(current_page)
        data_list = list()
        for i, msg_obj in enumerate(page.object_list):
            item = dict()
            item['id'] = i + 1
            item['title'] = msg_obj.title
            item['push_time'] = str(msg_obj.push_time)
            item['real_id'] = msg_obj.id
            item['status'] = msg_obj.status
            data_list.append(item)
        resp = {"code": 0, "count": msg_objs.count(), "data": data_list}
        return JsonResponse(resp)
    else:
        pass
    return render(request, 'message.html', locals())


@util.user_login
def handle_message(request):
    """对消息中心的数据进行变更操作，如删除，标记已查看"""
    print(request.method)
    if request.method == 'DELETE':
        arg = request_body_serialize(request)
        r_id = arg.get('real_id')
        obj = TdsdMessage.objects.filter(id=r_id, isdelete=0)
        if obj.count() == 1:
            try:
                with transaction.atomic():
                    obj.update(isdelete=1)
            except Exception as e:
                return JsonResponse({'code': 2, 'msg': str(e)})
            return JsonResponse({'code': 0, 'msg': 'Success'})
        else:
            return JsonResponse({'code': 1, 'msg': '你想要操作的资源缺失'})
    else:
        pass


@util.user_login
def message_detail(request, real_id):
    """
    点击进入详情页的视图函数，返回消息详情页
    :param request:
    :param real_id: 资源在数据库中的真实id
    :return:
    """
    # 根据real_id在数据库找到对应的信息，修改为已读，然后返回
    msg_obj = TdsdMessage.objects.filter(id=real_id, isdelete=0)
    try:
        with transaction.atomic():
            msg_obj.update(status='1')
    except Exception as e:
        return HttpResponse('获取详情失败')  # TODO 需要优化
    msg_obj = msg_obj.first()
    if '拒绝' in msg_obj.title:
        refuse = True
    return render(request, 'message_detail.html', locals())

# 需要删除
# @api_verification  # get_resource = verify_use_api(get_resource)
# def get_resource(request, resource_id):
#     """看测试调用api接口，本函数只处理根据资源id获取资源内容"""
#     print(resource_id)
#     obj = TdsdResourceList.objects.filter(resource_id=resource_id).first()  # 经过装饰器，资源确定是存在的
#     print(obj.resource_info)
#     return HttpResponse(obj.resource_info)
